import pygame
import random
import sys
import time

# 初始化pygame
pygame.init()

# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
LIGHT_GRAY = (200, 200, 200)
DARK_GRAY = (100, 100, 100)

# 设置显示窗口
WIDTH = 800
HEIGHT = 600
game_display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('贪吃蛇游戏 - 鼠标控制版')

# 蛇的大小和速度
SNAKE_SIZE = 20
SNAKE_SPEED = 10

# 初始化字体
large_font = pygame.font.SysFont(None, 50)
small_font = pygame.font.SysFont(None, 30)

def display_text(text, color, font, x, y):
    text_render = font.render(text, True, color)
    game_display.blit(text_render, [x, y])

# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, color, hover_color):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.hover_color = hover_color
        self.current_color = color
        
    def draw(self):
        pygame.draw.rect(game_display, self.current_color, self.rect)
        pygame.draw.rect(game_display, BLACK, self.rect, 2)  # 边框
        
        # 居中显示文本
        text_render = small_font.render(self.text, True, BLACK)
        text_x = self.rect.x + (self.rect.width - text_render.get_width()) // 2
        text_y = self.rect.y + (self.rect.height - text_render.get_height()) // 2
        game_display.blit(text_render, [text_x, text_y])
    
    def check_click(self, pos):
        if self.rect.collidepoint(pos):
            return True
        return False
    
    def update(self, mouse_pos):
        if self.rect.collidepoint(mouse_pos):
            self.current_color = self.hover_color
        else:
            self.current_color = self.color

def game_main_loop():
    # 游戏结束标志
    game_over = False
    game_exit = False
    
    # 创建方向按钮
    button_size = 60
    button_spacing = 10
    
    # 按钮位置计算，放在游戏区域右侧
    control_area_x = WIDTH - button_size * 3 - button_spacing * 2
    control_area_y = HEIGHT // 2 - button_size * 1.5
    
    up_button = Button(control_area_x + button_size + button_spacing, control_area_y, 
                      button_size, button_size, "上", LIGHT_GRAY, DARK_GRAY)
    down_button = Button(control_area_x + button_size + button_spacing, 
                        control_area_y + button_size * 2 + button_spacing, 
                        button_size, button_size, "下", LIGHT_GRAY, DARK_GRAY)
    left_button = Button(control_area_x, control_area_y + button_size + button_spacing, 
                        button_size, button_size, "左", LIGHT_GRAY, DARK_GRAY)
    right_button = Button(control_area_x + button_size * 2 + button_spacing * 2, 
                         control_area_y + button_size + button_spacing, 
                         button_size, button_size, "右", LIGHT_GRAY, DARK_GRAY)
    
    # 游戏区域
    game_area_width = control_area_x - 20
    
    # 蛇的初始位置
    snake_x = game_area_width / 2
    snake_y = HEIGHT / 2
    
    # 蛇的移动方向（初始不动）
    snake_x_change = 0
    snake_y_change = 0
    
    # 记录移动的最后一个方向
    last_direction = ""
    
    # 食物位置
    food_x = round(random.randrange(0, game_area_width - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
    food_y = round(random.randrange(0, HEIGHT - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
    
    # 蛇身体
    snake_body = []
    snake_length = 1
    
    # 得分
    score = 0
    
    # 显示开始说明
    game_display.fill(WHITE)
    display_text("点击开始按钮开始游戏", BLACK, large_font, WIDTH/6, HEIGHT/3)
    display_text("使用方向按钮控制蛇的移动", BLACK, small_font, WIDTH/6, HEIGHT/3 + 50)
    start_button = Button(WIDTH/2 - 75, HEIGHT/2, 150, 50, "开始游戏", GREEN, (0, 200, 0))
    start_button.draw()
    pygame.display.update()
    
    # 等待开始游戏
    waiting_to_start = True
    while waiting_to_start:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if start_button.check_click(event.pos):
                    waiting_to_start = False
        
        # 更新按钮颜色
        start_button.update(pygame.mouse.get_pos())
        start_button.draw()
        pygame.display.update()
    
    # 主游戏循环
    clock = pygame.time.Clock()
    last_update_time = time.time()
    
    # 绘制游戏边界
    def draw_game_boundary():
        pygame.draw.line(game_display, BLACK, (game_area_width, 0), (game_area_width, HEIGHT), 2)
    
    while not game_exit:
        
        current_time = time.time()
        time_diff = current_time - last_update_time
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_exit = True
            
            # 检测鼠标点击
            if event.type == pygame.MOUSEBUTTONDOWN:
                if up_button.check_click(event.pos) and last_direction != "down":
                    snake_y_change = -SNAKE_SIZE
                    snake_x_change = 0
                    last_direction = "up"
                    print("向上移动")
                elif down_button.check_click(event.pos) and last_direction != "up":
                    snake_y_change = SNAKE_SIZE
                    snake_x_change = 0
                    last_direction = "down"
                    print("向下移动")
                elif left_button.check_click(event.pos) and last_direction != "right":
                    snake_x_change = -SNAKE_SIZE
                    snake_y_change = 0
                    last_direction = "left"
                    print("向左移动")
                elif right_button.check_click(event.pos) and last_direction != "left":
                    snake_x_change = SNAKE_SIZE
                    snake_y_change = 0
                    last_direction = "right"
                    print("向右移动")
        
        # 更新按钮颜色
        mouse_pos = pygame.mouse.get_pos()
        up_button.update(mouse_pos)
        down_button.update(mouse_pos)
        left_button.update(mouse_pos)
        right_button.update(mouse_pos)
        
        # 只有当足够的时间过去时才更新位置
        if time_diff >= 1.0 / SNAKE_SPEED:
            last_update_time = current_time
            
            # 移动蛇
            if snake_x_change != 0 or snake_y_change != 0:  # 只有当蛇在移动时才更新位置
                snake_x += snake_x_change
                snake_y += snake_y_change
                
                # 检查是否撞墙
                if snake_x >= game_area_width or snake_x < 0 or snake_y >= HEIGHT or snake_y < 0:
                    game_over = True
                
                # 更新蛇身
                snake_head = []
                snake_head.append(snake_x)
                snake_head.append(snake_y)
                snake_body.append(snake_head)
                
                # 控制蛇的长度
                if len(snake_body) > snake_length:
                    del snake_body[0]
                
                # 检查是否撞到自己
                for segment in snake_body[:-1]:
                    if segment == snake_head:
                        game_over = True
                
                # 检查是否吃到食物
                if snake_x == food_x and snake_y == food_y:
                    food_x = round(random.randrange(0, game_area_width - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
                    food_y = round(random.randrange(0, HEIGHT - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
                    snake_length += 1
                    score += 1
        
        # 绘制游戏界面
        game_display.fill(WHITE)
        
        # 绘制游戏边界
        draw_game_boundary()
        
        # 绘制方向按钮
        up_button.draw()
        down_button.draw()
        left_button.draw()
        right_button.draw()
        
        # 绘制食物
        pygame.draw.rect(game_display, RED, [food_x, food_y, SNAKE_SIZE, SNAKE_SIZE])
        
        # 绘制蛇
        for segment in snake_body:
            pygame.draw.rect(game_display, GREEN, [segment[0], segment[1], SNAKE_SIZE, SNAKE_SIZE])
        
        # 显示得分
        display_text(f"得分: {score}", BLACK, large_font, 10, 10)
        
        # 如果还没有开始移动，显示提示
        if not snake_body:
            display_text("点击方向按钮开始移动", BLACK, small_font, 10, HEIGHT - 30)
        
        # 显示当前方向
        if last_direction:
            display_text(f"当前方向: {last_direction}", BLACK, small_font, 10, 50)
        
        # 更新显示
        pygame.display.update()
        
        # 游戏结束处理
        if game_over:
            game_display.fill(WHITE)
            display_text("游戏结束！得分: " + str(score), RED, large_font, WIDTH/6, HEIGHT/3)
            restart_button = Button(WIDTH/2 - 75, HEIGHT/2, 150, 50, "重新开始", GREEN, (0, 200, 0))
            exit_button = Button(WIDTH/2 - 75, HEIGHT/2 + 70, 150, 50, "退出游戏", RED, (200, 0, 0))
            
            end_loop = True
            while end_loop:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        if restart_button.check_click(event.pos):
                            game_main_loop()
                            return  # 防止递归调用堆栈溢出
                        if exit_button.check_click(event.pos):
                            pygame.quit()
                            sys.exit()
                
                # 更新按钮颜色
                mouse_pos = pygame.mouse.get_pos()
                restart_button.update(mouse_pos)
                exit_button.update(mouse_pos)
                
                # 绘制按钮
                restart_button.draw()
                exit_button.draw()
                pygame.display.update()
        
        # 控制游戏速度
        clock.tick(60)  # 固定帧率为60，但蛇的移动速度由时间差控制

    pygame.quit()
    sys.exit()

# 开始游戏
try:
    game_main_loop()
except Exception as e:
    print(f"游戏出错: {e}")
    pygame.quit()
    sys.exit()
